/*******************************************************************************
 *
 * File Name:          AdminActivity.java
 *
 * Created:            2006-10-19 21:05:35
 *
 * Original Author:    yu.peng
 *
 *------------------------------------------------------------------------------
 * MODIFICATION HISTORY
 *------------------------------------------------------------------------------
 * WHEN                WHO                 WHY
 * 2006-10-19 21:05:35 yu.peng             new
 *------------------------------------------------------------------------------
 *
 ******************************************************************************/
/*******************/
/* PACKAGE SECTION */
/*******************/
package org.njo.webapp.root.model.activity;

import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;
import org.njo.webapp.root.utility.SystemContext;
import org.njo.webapp.root.utility.ObjectNotExistsException;
import org.njo.webapp.root.utility.ObjectExistsException;
import org.njo.webapp.root.model.dao.*;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.ArrayList;

/**
 * TODO:comment
 *
 * @author yu.peng
 * @version 0.01
 */
public class UseerAdminActivity {

    /**
     * Log Object.
     */
    private static Log logger = LogFactory.getLog(UseerAdminActivity.class);

    /**
     * Remove the User from Database.
     *
     * @param argUsername User's Name
     */
    public void removeUser(String argUsername) throws ObjectNotExistsException {
        Connection connection = null;
        UsersDAO usersDAO = null;
        Users_rolesDAO users_rolesDAO = null;
        Users_groupsDAO users_groupsDAO = null;
        int deletedCount = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            usersDAO = new UsersDAO(connection);
            users_rolesDAO = new Users_rolesDAO(connection);
            users_groupsDAO = new Users_groupsDAO(connection);

            users_rolesDAO.deleteByUser_name(argUsername);
            users_groupsDAO.deleteByUser_name(argUsername);

            deletedCount = usersDAO.delete(argUsername);

            if (deletedCount != 1) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                throw new ObjectNotExistsException("there haven't in database.");
            }
            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * Remove the Users from Database.
     *
     * @param argUsernames User's Names
     */
    public void removeUsers(String[] argUsernames) throws ObjectNotExistsException {
        Connection connection = null;
        UsersDAO usersDAO = null;
        Users_rolesDAO users_rolesDAO = null;
        Users_groupsDAO users_groupsDAO = null;

        int deletedCount = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            usersDAO = new UsersDAO(connection);
            users_rolesDAO = new Users_rolesDAO(connection);
            users_groupsDAO = new Users_groupsDAO(connection);

            for (int i = 0;argUsernames!=null && i < argUsernames.length; i++) {
                String username = argUsernames[i];
                users_rolesDAO.deleteByUser_name(username);
                users_groupsDAO.deleteByUser_name(username);
                deletedCount += usersDAO.delete(username);
            }

            if (deletedCount != argUsernames.length) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                if (argUsernames!=null) {
                    throw new ObjectNotExistsException("will delete " + argUsernames.length
                            + " records from Users,but there are "
                            + deletedCount + " in Users");
                }
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * Remove all Users from Database.
     */
    public void removeAllUser() {
        Connection connection = null;
        UsersDAO usersDAO = null;
        Users_rolesDAO users_rolesDAO = null;
        Users_groupsDAO users_groupsDAO = null;

        int deletedCount = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            usersDAO = new UsersDAO(connection);
            users_rolesDAO = new Users_rolesDAO(connection);
            users_groupsDAO = new Users_groupsDAO(connection);

            users_rolesDAO.deleteAllRecords();
            users_groupsDAO.deleteAllRecords();
            deletedCount = usersDAO.deleteAllRecords();
            if (deletedCount==0) {
                // TODO
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * Remove the Role from Database.
     *
     * @param argRolename Role's Name
     */
    public void removeRole(String argRolename) throws ObjectNotExistsException {
        Connection connection = null;
        RolesDAO rolesDAO = null;
        Users_rolesDAO users_rolesDAO = null;
        Groups_rolesDAO groups_rolesDAO = null;

        int deletedCount = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            rolesDAO = new RolesDAO(connection);
            users_rolesDAO = new Users_rolesDAO(connection);
            groups_rolesDAO = new Groups_rolesDAO(connection);

            users_rolesDAO.deleteByRole_name(argRolename);
            groups_rolesDAO.deleteByRole_name(argRolename);

            deletedCount = rolesDAO.delete(argRolename);

            if (deletedCount != 1) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                throw new ObjectNotExistsException("there haven't in database.");
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * Remove the Groups From Database.
     *
     * @param argRolenames Role's Names
     */
    public void removeRoles(String[] argRolenames) throws ObjectNotExistsException {
        Connection connection = null;
        RolesDAO rolesDAO = null;
        Users_rolesDAO users_rolesDAO = null;
        Groups_rolesDAO groups_rolesDAO = null;
        int deletedCount = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            rolesDAO = new RolesDAO(connection);
            users_rolesDAO = new Users_rolesDAO(connection);
            groups_rolesDAO = new Groups_rolesDAO(connection);

            for (int i = 0; i < argRolenames.length; i++) {
                String rolename = argRolenames[i];
                users_rolesDAO.deleteByRole_name(rolename);
                groups_rolesDAO.deleteByRole_name(rolename);
                deletedCount += rolesDAO.delete(rolename);
            }

            if (deletedCount != argRolenames.length) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                throw new ObjectNotExistsException("will delete " + argRolenames.length
                        + " records from Roles, but there are "
                        + deletedCount + " in Roles");
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }

    }

    /**
     * Remove all groups from Database.
     */
    public void removeAllRoles() {
        Connection connection = null;
        RolesDAO rolesDAO = null;
        Users_rolesDAO users_rolesDAO = null;
        Groups_rolesDAO groups_rolesDAO = null;

        int deletedCount = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            rolesDAO = new RolesDAO(connection);
            users_rolesDAO = new Users_rolesDAO(connection);
            groups_rolesDAO = new Groups_rolesDAO(connection);

            users_rolesDAO.deleteAllRecords();
            groups_rolesDAO.deleteAllRecords();
            deletedCount = rolesDAO.deleteAllRecords();
            if (deletedCount==0) {
                // TODO
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * Remove the Group from Database.
     *
     * @param argGroupname Group's Name
     */
    public void removeGroup(String argGroupname) throws ObjectNotExistsException {
        Connection connection = null;
        GroupsDAO groupsDAO = null;
        Groups_rolesDAO groups_rolesDAO = null;
        Users_groupsDAO users_groupsDAO = null;
        int deletedCount = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            groupsDAO = new GroupsDAO(connection);
            groups_rolesDAO = new Groups_rolesDAO(connection);
            users_groupsDAO = new Users_groupsDAO(connection);

            groups_rolesDAO.deleteByGroup_name(argGroupname);
            users_groupsDAO.deleteByGroup_name(argGroupname);

            deletedCount = groupsDAO.delete(argGroupname);

            if (deletedCount != 1) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                throw new ObjectNotExistsException("there haven't in database.");
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }

    }

    /**
     * Remove the Groups From Database.
     *
     * @param argGroupnames Group's Names
     */
    public void removeGroups(String[] argGroupnames) throws ObjectNotExistsException {
        Connection connection = null;
        GroupsDAO groupsDAO = null;
        Groups_rolesDAO groups_rolesDAO = null;
        Users_groupsDAO users_groupsDAO = null;

        int deletedCount = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            groupsDAO = new GroupsDAO(connection);
            groups_rolesDAO = new Groups_rolesDAO(connection);
            users_groupsDAO = new Users_groupsDAO(connection);

            for (int i = 0;argGroupnames!=null && i < argGroupnames.length; i++) {
                String groupname = argGroupnames[i];
                groups_rolesDAO.deleteByGroup_name(groupname);
                users_groupsDAO.deleteByGroup_name(groupname);
                deletedCount += groupsDAO.delete(groupname);
            }

            if (deletedCount != argGroupnames.length) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                if (argGroupnames!=null) {
                    throw new ObjectNotExistsException("will delete " + argGroupnames.length
                            + " records from Groups,but there are "
                            + deletedCount + " in Groups");
                }
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }

    }

    /**
     * Remove all groups from Database.
     */
    public void removeAllGroups() {
        Connection connection = null;
        GroupsDAO groupsDAO = null;
        Groups_rolesDAO groups_rolesDAO = null;
        Users_groupsDAO users_groupsDAO = null;
        int deletedCount = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            groupsDAO = new GroupsDAO(connection);
            groups_rolesDAO = new Groups_rolesDAO(connection);
            users_groupsDAO = new Users_groupsDAO(connection);

            groups_rolesDAO.deleteAllRecords();
            users_groupsDAO.deleteAllRecords();
            deletedCount = groupsDAO.deleteAllRecords();
            if (deletedCount==0) {
                // TODO
            }
            
            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public void addUser(String argUserName,
                        String argPassword,
                        String argDescription,
                        String[] argGroupsName,
                        String[] argRolesName) throws ObjectExistsException {
        Connection connection = null;
        UsersDAO usersDAO = null;
        Users_rolesDAO users_rolesDAO = null;
        Users_groupsDAO users_groupsDAO = null;
        int count = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            usersDAO = new UsersDAO(connection);
            count = usersDAO.insert(argUserName, argPassword, argDescription);

            users_groupsDAO = new Users_groupsDAO(connection);
            count = users_groupsDAO.deleteByUser_name(argUserName);
            // Add the user with group into users_groups.
            for (int i = 0;argGroupsName!=null && i < argGroupsName.length; i++) {
                String groupName = argGroupsName[i];
                count = users_groupsDAO.insert(argUserName, groupName);
            }

            users_rolesDAO = new Users_rolesDAO(connection);
            count = users_rolesDAO.deleteByUser_name(argUserName);
            // Add the user with role into users_roles.
            for (int i = 0;argRolesName!=null && i < argRolesName.length; i++) {
                String roleName = argRolesName[i];
                count = users_rolesDAO.insert(argUserName, roleName);
            }
            if (count==0) {
                
            }
            
            
            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            if (ex.getErrorCode() == 1) {
                throw new ObjectExistsException("aready inserted.");
            }

            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * 更新用户信息.
     *
     * 注意:这个方法会重置密码.
     *
     * @param argUserName
     * @param argPassword
     * @param argDescription
     * @param argGroupsName
     * @param argRolesName
     * @throws ObjectNotExistsException
     */
    public void updateUser(String argUserName,
                           String argPassword,
                           String argDescription,
                           String[] argGroupsName,
                           String[] argRolesName) throws ObjectNotExistsException {
        Connection connection = null;
        UsersDAO usersDAO = null;
        Users_rolesDAO users_rolesDAO = null;
        Users_groupsDAO users_groupsDAO = null;
        int count = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            usersDAO = new UsersDAO(connection);
            count = usersDAO.update(argUserName, argPassword, argDescription);

            if (count != 1) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                throw new ObjectNotExistsException("there haven't in database.");
            }


            users_groupsDAO = new Users_groupsDAO(connection);
            count = users_groupsDAO.deleteByUser_name(argUserName);
            // Add the user with group into users_groups.
            for (int i = 0;argGroupsName!=null && i < argGroupsName.length; i++) {
                String groupName = argGroupsName[i];
                count = users_groupsDAO.insert(argUserName, groupName);
            }

            users_rolesDAO = new Users_rolesDAO(connection);
            count = users_rolesDAO.deleteByUser_name(argUserName);
            // Add the user with role into users_roles.
            for (int i = 0;argRolesName!=null && i < argRolesName.length; i++) {
                String roleName = argRolesName[i];
                count = users_rolesDAO.insert(argUserName, roleName);
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * 更新用户信息.
     *
     * 注意:这个方法不重置密码.
     *
     * @param argUserName
     * @param argDescription
     * @param argGroupsName
     * @param argRolesName
     * @throws ObjectNotExistsException
     */
    public void updateUser(String argUserName,
                           String argDescription,
                           String[] argGroupsName,
                           String[] argRolesName) throws ObjectNotExistsException {
        Connection connection = null;
        UsersDAO usersDAO = null;
        Users_rolesDAO users_rolesDAO = null;
        Users_groupsDAO users_groupsDAO = null;
        int count = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            usersDAO = new UsersDAO(connection);
            count = usersDAO.update(argUserName, argDescription);

            if (count != 1) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                throw new ObjectNotExistsException("there haven't in database.");
            }


            users_groupsDAO = new Users_groupsDAO(connection);
            count = users_groupsDAO.deleteByUser_name(argUserName);
            // Add the user with group into users_groups.
            for (int i = 0;argGroupsName!=null && i < argGroupsName.length; i++) {
                String groupName = argGroupsName[i];
                count = users_groupsDAO.insert(argUserName, groupName);
            }

            users_rolesDAO = new Users_rolesDAO(connection);
            count = users_rolesDAO.deleteByUser_name(argUserName);
            // Add the user with role into users_roles.
            for (int i = 0;argRolesName!=null && i < argRolesName.length; i++) {
                String roleName = argRolesName[i];
                count = users_rolesDAO.insert(argUserName, roleName);
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * @param argRoleName
     * @param argDescription
     * @throws ObjectExistsException
     */
    public void addRole(String argRoleName, String argDescription) throws ObjectExistsException {
        Connection connection = null;
        RolesDAO rolesDAO = null;
        int count = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            rolesDAO = new RolesDAO(connection);
            count = rolesDAO.insert(argRoleName, argDescription);
            if (count==0) {
                
            }
            
            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }

            if (ex.getErrorCode() == 1) {
                throw new ObjectExistsException("aready inserted.");
            }

            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * @param argRoleName
     * @param argDescription
     * @throws ObjectNotExistsException
     */
    public void updateRole(String argRoleName, String argDescription) throws ObjectNotExistsException {
        Connection connection = null;
        RolesDAO rolesDAO = null;
        int count = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            rolesDAO = new RolesDAO(connection);
            count = rolesDAO.update(argRoleName, argDescription);

            if (count != 1) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                throw new ObjectNotExistsException("there haven't in database.");
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * @param argGroupName
     * @param argDescription
     * @param argRolesName
     * @throws ObjectExistsException
     */
    public void addGroup(String argGroupName, String argDescription, String[] argRolesName) throws ObjectExistsException {
        Connection connection = null;
        GroupsDAO groupsDAO = null;
        Groups_rolesDAO groups_rolesDAO = null;
        int count = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            groupsDAO = new GroupsDAO(connection);
            count = groupsDAO.insert(argGroupName, argDescription);

            groups_rolesDAO = new Groups_rolesDAO(connection);
            count = groups_rolesDAO.deleteByGroup_name(argGroupName);

            // Add the group with role into groups_roles.
            for (int i = 0;argRolesName!=null && i < argRolesName.length; i++) {
                String argRoleName = argRolesName[i];
                count = groups_rolesDAO.insert(argGroupName, argRoleName);
            }
            if (count==0) {
                // TODO
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }

            if (ex.getErrorCode() == 1) {
                throw new ObjectExistsException("aready inserted.");
            }

            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * @param argGroupName
     * @param argDescription
     * @param argRolesName
     * @throws ObjectNotExistsException
     */
    public void updateGroup(String argGroupName, String argDescription, String[] argRolesName) throws ObjectNotExistsException {
        Connection connection = null;
        GroupsDAO groupsDAO = null;
        Groups_rolesDAO groups_rolesDAO = null;
        int count = 0;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            groupsDAO = new GroupsDAO(connection);
            count = groupsDAO.update(argGroupName, argDescription);

            if (count != 1) {
                try {
                    connection.rollback();
                } catch (Throwable tw) {
                    // when rollback fail,log the info.
                    logger.error(tw);
                }
                throw new ObjectNotExistsException("there haven't in database.");
            }


            groups_rolesDAO = new Groups_rolesDAO(connection);
            count = groups_rolesDAO.deleteByGroup_name(argGroupName);

            // Add the group with role into groups_roles.
            for (int i = 0;argRolesName!=null && i < argRolesName.length; i++) {
                String argRoleName = argRolesName[i];
                count = groups_rolesDAO.insert(argGroupName, argRoleName);
            }

            connection.commit();
        } catch (SQLException ex) {
            // when fail rollback the updated's data.
            try {
                connection.rollback();
            } catch (Throwable tw) {
                // when rollback fail,log the info.
                logger.error(tw);
            }

            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * @return userList
     */
    public List getUsers() {
        Connection connection = null;
        UsersDAO usersDAO = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            usersDAO = new UsersDAO(connection);
            return usersDAO.selectAllRecords();
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * @return user
     */
    public String[] getUsers(String argUserName) throws ObjectNotExistsException {
        Connection connection = null;
        UsersDAO usersDAO = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            usersDAO = new UsersDAO(connection);
            return usersDAO.selectByName(argUserName);
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    /**
     * @return username
     */
    public String[] getUsersName() {
        List usersList = getUsers();
        List usersName = new ArrayList();
        for (int i = 0; i < usersList.size(); i++) {
            String[] user = (String[]) usersList.get(i);
            usersName.add(user[0]);
        }
        return (String[]) usersName.toArray(new String[usersName.size()]);
    }

    public List getRoles() {
        Connection connection = null;
        RolesDAO rolesDAO = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            rolesDAO = new RolesDAO(connection);
            return rolesDAO.selectAllRecords();
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public String[] getRoles(String argRoleName) throws ObjectNotExistsException {
        Connection connection = null;
        RolesDAO rolesDAO = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            rolesDAO = new RolesDAO(connection);
            return rolesDAO.selectByName(argRoleName);
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public String[] getRolesName() {
        List rolesList = getRoles();
        List rolesName = new ArrayList();
        for (int i = 0; i < rolesList.size(); i++) {
            String[] role = (String[]) rolesList.get(i);
            rolesName.add(role[0]);
        }
        return (String[]) rolesName.toArray(new String[rolesName.size()]);
    }

    public List getRolesByGroup(String argGroup) throws ObjectNotExistsException {
        Connection connection = null;
        Groups_rolesDAO groups_rolesDAO = null;
        RolesDAO rolesDAO = null;
        List groups_rolesList = null;
        List rolesList = new ArrayList();

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            groups_rolesDAO = new Groups_rolesDAO(connection);
            rolesDAO = new RolesDAO(connection);

            groups_rolesList = groups_rolesDAO.selectByGroup(argGroup);
            // decode to Roles.
            for (int i = 0; i < groups_rolesList.size(); i++) {
                String[] groups_roles = (String[]) groups_rolesList.get(i);
                String[] role = rolesDAO.selectByName(groups_roles[1]);
                rolesList.add(role);
            }

            return rolesList;
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public String[] getRolesNameByGroup(String argGroup) throws ObjectNotExistsException {
        List rolesList = getRolesByGroup(argGroup);
        List rolesName = new ArrayList();
        for (int i = 0; i < rolesList.size(); i++) {
            String[] role = (String[]) rolesList.get(i);
            rolesName.add(role[0]);
        }
        return (String[]) rolesName.toArray(new String[rolesName.size()]);
    }

    public List getRolesByUser(String argUser) throws ObjectNotExistsException {
        Connection connection = null;
        Users_rolesDAO users_rolesDAO = null;
        RolesDAO rolesDAO = null;
        List users_rolesList = null;
        List rolesList = new ArrayList();

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            users_rolesDAO = new Users_rolesDAO(connection);
            rolesDAO = new RolesDAO(connection);

            users_rolesList = users_rolesDAO.selectByUser(argUser);
            // decode to Roles.
            for (int i = 0; i < users_rolesList.size(); i++) {
                String[] users_roles = (String[]) users_rolesList.get(i);
                String[] role = rolesDAO.selectByName(users_roles[1]);
                rolesList.add(role);
            }
            return rolesList;
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public String[] getRolesNameByUser(String argUser) throws ObjectNotExistsException {
        List rolesList = getRolesByUser(argUser);
        List rolesName = new ArrayList();
        for (int i = 0; i < rolesList.size(); i++) {
            String[] role = (String[]) rolesList.get(i);
            rolesName.add(role[0]);
        }
        return (String[]) rolesName.toArray(new String[rolesName.size()]);
    }

    public List getGroups() {
        Connection connection = null;
        GroupsDAO groupsDAO = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            groupsDAO = new GroupsDAO(connection);
            return groupsDAO.selectAllRecords();
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public String[] getGroups(String argGroupName) throws ObjectNotExistsException {
        Connection connection = null;
        GroupsDAO groupsDAO = null;

        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            groupsDAO = new GroupsDAO(connection);
            return groupsDAO.selectByName(argGroupName);
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public String[] getGroupsName() {
        List groupsList = getGroups();
        List groupsName = new ArrayList();
        for (int i = 0; i < groupsList.size(); i++) {
            String[] group = (String[]) groupsList.get(i);
            groupsName.add(group[0]);
        }
        return (String[]) groupsName.toArray(new String[groupsName.size()]);
    }

    public List getGroupsByUser(String argUser) throws ObjectNotExistsException {
        Connection connection = null;
        Users_groupsDAO users_groupsDAO = null;
        GroupsDAO groupsDAO = null;
        List users_groupsList = null;

        List groupsList = new ArrayList();
        // open the database connection.
        try {
            connection = SystemContext.openConnection();
        } catch (Throwable tw) {
            logger.error(tw);
            throw new RuntimeException(tw);
        }

        // access the database.
        try {
            users_groupsDAO = new Users_groupsDAO(connection);
            groupsDAO = new GroupsDAO(connection);

            users_groupsList = users_groupsDAO.selectByUser(argUser);
            // decode to Groups.
            for (int i = 0; i < users_groupsList.size(); i++) {
                String[] users_groups = (String[]) users_groupsList.get(i);
                String[] group = groupsDAO.selectByName(users_groups[1]);
                groupsList.add(group);
            }
            return groupsList;
        } catch (SQLException ex) {
            logger.error(ex);
            throw new RuntimeException(ex);
        } finally {
            try {
                if (connection != null) {
                    SystemContext.closeConnection(connection);
                }
            } catch (Throwable tw) {
            }
        }
    }

    public String[] getGroupsNameByUser(String argUser) {
        List groupsList = getGroupsByUser(argUser);
        List groupsName = new ArrayList();
        for (int i = 0; i < groupsList.size(); i++) {
            String[] group = (String[]) groupsList.get(i);
            groupsName.add(group[0]);
        }
        return (String[]) groupsName.toArray(new String[groupsName.size()]);
    }

}
